home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 14 / Example 14.1 / effect.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-07-16  |  21.8 KB  |  696 lines

  1. #include "effect.h"
  2. #include "particles.h"
  3.  
  4. //Global Effect variables
  5. ID3DXMesh *billboardMesh = NULL;
  6. D3DMATERIAL9 whiteMtrl;
  7. SHADER effectVertexShader, effectPixelShader, fireVertexShader, firePixelShader;
  8. D3DXHANDLE effectMatW, effectMatVP, effectVCol;
  9. D3DXHANDLE fireMatW, fireMatVP, fireTime, fireOffset, fireDirToCam;
  10. ID3DXSprite *sprite = NULL;
  11.  
  12. //Global Effect Textures
  13. IDirect3DTexture9* runesTexture = NULL;
  14. IDirect3DTexture9* cloudTexture = NULL;
  15. IDirect3DTexture9* fireballTexture = NULL;
  16. IDirect3DTexture9* lensflareTexture = NULL;
  17. IDirect3DTexture9* noiseTexture = NULL;
  18. IDirect3DTexture9* fireTexture = NULL;
  19. IDirect3DTexture9* selectedTexture = NULL;
  20. IDirect3DTexture9* trainingTexture = NULL;
  21.  
  22. //Effect Pool
  23. std::vector<EFFECT*> effects;
  24.  
  25. struct SimpleVertex
  26. {
  27.     SimpleVertex(){}
  28.     SimpleVertex(D3DXVECTOR3 pos, D3DXVECTOR3 norm, D3DXVECTOR2 _uv)
  29.     {
  30.         position = pos;
  31.         normal = norm;
  32.         uv = _uv;
  33.     }
  34.  
  35.     D3DXVECTOR3 position, normal;
  36.     D3DXVECTOR2 uv;
  37.  
  38.     static const DWORD FVF;
  39. };
  40.  
  41. const DWORD SimpleVertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
  42.  
  43. void LoadEffectResources(IDirect3DDevice9 *m_pDevice)
  44. {
  45.     //Calculate sight mesh (a simple quad)
  46.     D3DXCreateMeshFVF(2, 4, D3DXMESH_MANAGED, SimpleVertex::FVF, m_pDevice, &billboardMesh);
  47.  
  48.     //Create 4 vertices
  49.     SimpleVertex* v = 0;
  50.     billboardMesh->LockVertexBuffer(0,(void**)&v);
  51.     v[0] = SimpleVertex(D3DXVECTOR3(-0.5f, 0.0f, 0.5f), D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(0, 0));
  52.     v[1] = SimpleVertex(D3DXVECTOR3( 0.5f, 0.0f, 0.5f), D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(1, 0));
  53.     v[2] = SimpleVertex(D3DXVECTOR3(-0.5f, 0.0f, -0.5f),D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(0, 1));
  54.     v[3] = SimpleVertex(D3DXVECTOR3( 0.5f, 0.0f, -0.5f),D3DXVECTOR3(0.0f, 1.0f, 0.0f), D3DXVECTOR2(1, 1));
  55.     billboardMesh->UnlockVertexBuffer();
  56.  
  57.     //Create 2 faces
  58.     WORD* indices = 0;
  59.     billboardMesh->LockIndexBuffer(0,(void**)&indices);    
  60.     indices[0] = 0; indices[1] = 1; indices[2] = 2;
  61.     indices[3] = 1; indices[4] = 3; indices[5] = 2;
  62.     billboardMesh->UnlockIndexBuffer();
  63.  
  64.     //Set Attributes for the 2 faces
  65.     DWORD *att = 0;
  66.     billboardMesh->LockAttributeBuffer(0,&att);
  67.     att[0] = 0; att[1] = 0;
  68.     billboardMesh->UnlockAttributeBuffer();
  69.  
  70.     //Sight MTRL
  71.     memset(&whiteMtrl, 0, sizeof(D3DMATERIAL9));
  72.     whiteMtrl.Diffuse = whiteMtrl.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
  73.  
  74.     //Load Shaders
  75.     effectVertexShader.Init(m_pDevice, "shaders/effect.vs", VERTEX_SHADER);
  76.     effectPixelShader.Init(m_pDevice, "shaders/effect.ps", PIXEL_SHADER);
  77.     fireVertexShader.Init(m_pDevice, "shaders/fire.vs", VERTEX_SHADER);
  78.     firePixelShader.Init(m_pDevice, "shaders/fire.ps", PIXEL_SHADER);
  79.  
  80.     //Get constants
  81.     effectMatW = effectVertexShader.GetConstant("matW");
  82.     effectMatVP = effectVertexShader.GetConstant("matVP");
  83.     effectVCol = effectVertexShader.GetConstant("vertexColor");
  84.     fireMatW = fireVertexShader.GetConstant("matW");
  85.     fireMatVP = fireVertexShader.GetConstant("matVP");
  86.     fireTime = fireVertexShader.GetConstant("time");
  87.     fireOffset = fireVertexShader.GetConstant("offset");
  88.     fireDirToCam = fireVertexShader.GetConstant("DirToCam");
  89.  
  90.     //Create Sprite
  91.     D3DXCreateSprite(m_pDevice, &sprite);
  92.  
  93.     //Load textures
  94.     D3DXCreateTextureFromFile(m_pDevice, "textures/runes.dds", &runesTexture);
  95.     D3DXCreateTextureFromFile(m_pDevice, "textures/cloud.dds", &cloudTexture);
  96.     D3DXCreateTextureFromFile(m_pDevice, "textures/fireball.dds", &fireballTexture);
  97.     D3DXCreateTextureFromFile(m_pDevice, "textures/lensflare.dds", &lensflareTexture);
  98.     D3DXCreateTextureFromFile(m_pDevice, "textures/noise.dds", &noiseTexture);
  99.     D3DXCreateTextureFromFile(m_pDevice, "textures/fire.dds", &fireTexture);
  100.     D3DXCreateTextureFromFile(m_pDevice, "textures/selected.dds", &selectedTexture);
  101.     D3DXCreateTextureFromFile(m_pDevice, "textures/training.dds", &trainingTexture);
  102. }
  103.  
  104. void UnloadEffectResources()
  105. {
  106.     if(billboardMesh)billboardMesh->Release();
  107.     billboardMesh = NULL;
  108.  
  109.     if(sprite)sprite->Release();
  110.     sprite = NULL;
  111.  
  112.     //Release textures
  113.     if(runesTexture)runesTexture->Release();
  114.     if(cloudTexture)cloudTexture->Release();
  115.     if(fireballTexture)fireballTexture->Release();
  116.     if(lensflareTexture)lensflareTexture->Release();
  117.     if(noiseTexture)noiseTexture->Release();
  118.     if(fireTexture)fireTexture->Release();
  119.     if(selectedTexture)selectedTexture->Release();
  120.     if(trainingTexture)trainingTexture->Release();
  121.  
  122.     runesTexture = NULL;
  123.     cloudTexture = NULL;
  124.     fireballTexture = NULL;
  125.     lensflareTexture = NULL;
  126.     noiseTexture = NULL;
  127.     fireTexture = NULL;
  128.     selectedTexture = NULL;
  129.     trainingTexture = NULL;
  130. }
  131.  
  132. //////////////////////////////////////////////////////////////////////////////////////////////
  133. //                                TRANSFORM                                                    //
  134. //////////////////////////////////////////////////////////////////////////////////////////////
  135.  
  136. TRANSFORM::TRANSFORM(){ m_pos = m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f); m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  137. TRANSFORM::TRANSFORM(D3DXVECTOR3 _pos){ m_pos = _pos; m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f); m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  138. TRANSFORM::TRANSFORM(D3DXVECTOR3 _pos, D3DXVECTOR3 _rot){ m_pos = _pos; m_rot = _rot; m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  139. TRANSFORM::TRANSFORM(D3DXVECTOR3 _pos, D3DXVECTOR3 _rot, D3DXVECTOR3 _sca){ m_pos = _pos; m_rot = _rot; m_sca = _sca; }
  140.  
  141. void TRANSFORM::Init(D3DXVECTOR3 _pos){ m_pos = _pos; m_rot = D3DXVECTOR3(0.0f, 0.0f, 0.0f); m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  142. void TRANSFORM::Init(D3DXVECTOR3 _pos, D3DXVECTOR3 _rot){ m_pos = _pos; m_rot = _rot; m_sca = D3DXVECTOR3(1.0f, 1.0f, 1.0f); }
  143. void TRANSFORM::Init(D3DXVECTOR3 _pos, D3DXVECTOR3 _rot, D3DXVECTOR3 _sca){ m_pos = _pos; m_rot = _rot; m_sca = _sca; }
  144.  
  145. D3DXMATRIX TRANSFORM::GetWorldMatrix()
  146. {
  147.     D3DXMATRIX p, r, s;
  148.     D3DXMatrixTranslation(&p, m_pos.x, m_pos.y, m_pos.z);
  149.     D3DXMatrixRotationYawPitchRoll(&r, m_rot.y, m_rot.x, m_rot.z);
  150.     D3DXMatrixScaling(&s, m_sca.x, m_sca.y, m_sca.z);
  151.     D3DXMATRIX world = s * r * p;
  152.     return world;
  153. }
  154.  
  155. //////////////////////////////////////////////////////////////////////////////////////////////
  156. //                                EFFECTS    BASE CLASS                                            //
  157. //////////////////////////////////////////////////////////////////////////////////////////////
  158.  
  159. EFFECT::EFFECT(IDirect3DDevice9 *Dev)
  160. {
  161.     m_pDevice = Dev;
  162.     m_time = 0.0f;
  163.     m_color = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);    //White
  164. }
  165.  
  166. void EFFECT::PreRender()
  167. {
  168.     //Enable alpha blending
  169.     m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  170.     m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
  171.     m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  172.     m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  173.     m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
  174.     m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  175.     m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE );
  176.     m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  177.     m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, false);
  178.     m_pDevice->SetRenderState(D3DRS_LIGHTING, false);
  179.  
  180.     //Set vertex shader variables
  181.     D3DXMATRIX view, proj;
  182.     m_pDevice->GetTransform(D3DTS_VIEW, &view);
  183.     m_pDevice->GetTransform(D3DTS_PROJECTION, &proj);
  184.     
  185.     effectVertexShader.SetMatrix(effectMatVP, view * proj);
  186.     effectVertexShader.SetVector4(effectVCol, m_color);
  187.  
  188.     //Set material
  189.     m_pDevice->SetMaterial(&whiteMtrl);
  190.  
  191.     //enable Shaders
  192.     effectVertexShader.Begin();
  193.     effectPixelShader.Begin();
  194. }
  195.  
  196. void EFFECT::PostRender()
  197. {
  198.     //Reset renderstates
  199.     m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
  200.     m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, true);
  201.     m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
  202.  
  203.     //Disable shaders
  204.     effectVertexShader.End();
  205.     effectPixelShader.End();
  206. }
  207.  
  208. //////////////////////////////////////////////////////////////////////////////////////////////
  209. //                                EFFECTS    SPELL                                                //
  210. //////////////////////////////////////////////////////////////////////////////////////////////
  211.  
  212. EFFECT_SPELL::EFFECT_SPELL(IDirect3DDevice9 *Dev, D3DXVECTOR3 _pos) : EFFECT(Dev), m_t1(_pos, D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(0.1f, 0.1f, 0.1f))
  213. {
  214.     m_t1.m_pos.y += 0.1f;
  215.     m_color = D3DXVECTOR4(0.2f, 0.3f, 1.0f, 0.0f);
  216.  
  217.     for(int i=0;i<10;i++)
  218.     {
  219.         float angle = i * (D3DX_PI / 5.0f);
  220.             
  221.         m_c[i].Init(_pos + D3DXVECTOR3(cos(angle) * 0.1f, 0.7f, sin(angle) * 0.1f),
  222.                   D3DXVECTOR3(D3DX_PI * 0.5f, angle, 0.0f),
  223.                   D3DXVECTOR3(1.5f, 1.5f, 2.5f));
  224.     }
  225. }
  226.  
  227. void EFFECT_SPELL::Update(float timeDelta)
  228. {
  229.     m_time += timeDelta;
  230.  
  231.     //Update Lower spinning quad...
  232.     m_t1.m_rot.y += timeDelta;
  233.  
  234.     //Update cloud
  235.     for(int i=0;i<10;i++)
  236.         m_c[i].m_rot.y -= timeDelta;
  237.  
  238.     //Update Spinning quad scale
  239.     if(m_time < 1.5f)m_t1.m_sca += D3DXVECTOR3(timeDelta, timeDelta, timeDelta) * 1.2f;
  240.     if(m_time > 4.5f)m_t1.m_sca -= D3DXVECTOR3(timeDelta, timeDelta, timeDelta) * 1.2f;
  241.  
  242.     //Calculate alpha
  243.     m_color.w = m_t1.m_sca.x / 6.0f;
  244. }
  245.  
  246. void EFFECT_SPELL::Render()
  247. {
  248.     PreRender();
  249.  
  250.     if(billboardMesh)
  251.     {
  252.         //Spinning quad
  253.         m_pDevice->SetTexture(0, runesTexture);
  254.         effectVertexShader.SetMatrix(effectMatW, m_t1.GetWorldMatrix());
  255.         billboardMesh->DrawSubset(0);
  256.  
  257.         //Cloud
  258.         m_pDevice->SetTexture(0, cloudTexture);
  259.         for(int i=0;i<10;i++)
  260.         {
  261.             effectVertexShader.SetMatrix(effectMatW, m_c[i].GetWorldMatrix());
  262.             billboardMesh->DrawSubset(0);
  263.         }
  264.     }
  265.  
  266.     PostRender();
  267. }
  268.  
  269. bool EFFECT_SPELL::isDead()
  270. {
  271.     return m_t1.m_sca.x < 0.0f;
  272. }
  273.  
  274. //////////////////////////////////////////////////////////////////////////////////////////////
  275. //                                EFFECTS    FIREBALL                                            //
  276. //////////////////////////////////////////////////////////////////////////////////////////////
  277.  
  278. EFFECT_FIREBALL::EFFECT_FIREBALL(IDirect3DDevice9 *Dev, D3DXVECTOR3 *bonePos, MAPOBJECT *_target, MAPOBJECT *_attacker) : EFFECT(Dev)
  279. {
  280.     m_pSrcBone = bonePos;
  281.     m_pTarget = _target;
  282.     m_pAttacker = _attacker;
  283.     dest = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  284.     m_color.w = 0.01f;
  285.     m_prc = 0.0f;
  286.     m_speed = 3.0f;
  287.     m_damage = m_pAttacker->m_damage;
  288.  
  289.     if(m_pTarget != NULL)
  290.         dest = m_pTarget->m_position + D3DXVECTOR3(0.0f, 1.0f, 0.0f);
  291.  
  292.     if(m_pSrcBone != NULL)
  293.         m_t1.Init(*m_pSrcBone, D3DXVECTOR3(0.0f, 0.0f, 0.0f), D3DXVECTOR3(1.0f, 1.0f, 1.0f));
  294. }
  295.  
  296. void EFFECT_FIREBALL::Update(float timeDelta)
  297. {
  298.     try
  299.     {
  300.         m_t1.m_rot += D3DXVECTOR3(0.5f, 0.5f, 0.5f) * timeDelta;        
  301.  
  302.         if(m_pTarget != NULL)
  303.         {
  304.             dest = m_pTarget->m_position + D3DXVECTOR3(0.0f, 1.0f, 0.0f);
  305.             if(m_pTarget->m_dead)m_color.w -= timeDelta * 0.5f;
  306.         }
  307.  
  308.         if(m_time < 1.0f && m_pSrcBone != NULL)        //Follow staff
  309.         {
  310.             m_time += timeDelta;
  311.             m_t1.m_pos = *m_pSrcBone;        //Extract position from bone
  312.             m_t1.m_sca = D3DXVECTOR3(0.3f, 0.3f, 0.3f) * m_time;
  313.             m_color.w = m_time;
  314.  
  315.             if(m_time > 1.0f)
  316.             {
  317.                 m_color.w = m_time * 0.5f;
  318.                 origin = m_t1.m_pos;
  319.                 m_length = D3DXVec3Length(&(origin - dest));
  320.             }
  321.         }
  322.         else if(m_prc < 1.0f)        //Fly towards target
  323.         {
  324.             m_prc += (m_speed * timeDelta) / m_length;
  325.             m_t1.m_pos = GetPosition(m_prc);
  326.  
  327.             if(m_prc >= 1.0f && m_pTarget != NULL)
  328.                 m_pTarget->Damage(m_damage, m_pAttacker);
  329.         }
  330.         else                    //Explode
  331.         {
  332.             m_prc += (m_speed * timeDelta) / m_length;
  333.             m_t1.m_sca += D3DXVECTOR3(1.0f, 1.0f, 1.0f) * timeDelta;
  334.             m_color.w -= timeDelta * 0.5f;
  335.         }
  336.     }
  337.     catch(...){}
  338. }
  339.  
  340. void EFFECT_FIREBALL::Render()
  341. {
  342.     PreRender();
  343.  
  344.     if(billboardMesh)
  345.     {
  346.         D3DXVECTOR3 orgRot = m_t1.m_rot;
  347.         D3DXVECTOR3 rotations[] = {D3DXVECTOR3(0.0f, 0.0f, 0.0f),
  348.                                    D3DXVECTOR3(D3DX_PI * 0.5f, 0.0f, 0.0f),
  349.                                    D3DXVECTOR3(0.0f, D3DX_PI * 0.5f, 0.0f),
  350.                                    D3DXVECTOR3(0.0f, 0.0f, D3DX_PI * 0.5f)};
  351.  
  352.         D3DXVECTOR3 orgPos = m_t1.m_pos;
  353.         D3DXVECTOR3 positions[] = {m_t1.m_pos, 
  354.                                    GetPosition(m_prc - (0.15f / m_length)),
  355.                                    GetPosition(m_prc - (0.25f / m_length)),
  356.                                    GetPosition(m_prc - (0.35f / m_length)),
  357.                                    GetPosition(m_prc - (0.40f / m_length))};
  358.  
  359.         D3DXVECTOR3 orgSca = m_t1.m_sca;
  360.         D3DXVECTOR3 scales[] = {m_t1.m_sca, 
  361.                                 m_t1.m_sca * 0.8f,
  362.                                 m_t1.m_sca * 0.6f,
  363.                                 m_t1.m_sca * 0.4f,
  364.                                 m_t1.m_sca * 0.2f};
  365.     
  366.         m_pDevice->SetTexture(0, fireballTexture);
  367.         for(int t=0;t<5;t++)
  368.             for(int i=0;i<4;i++)
  369.             {
  370.                 m_t1.m_pos = positions[t];
  371.                 m_t1.m_rot = orgRot + rotations[i];
  372.                 m_t1.m_sca = scales[t];
  373.  
  374.                 effectVertexShader.SetMatrix(effectMatW, m_t1.GetWorldMatrix());
  375.                 billboardMesh->DrawSubset(0);
  376.             }
  377.  
  378.         m_t1.m_pos = orgPos;
  379.         m_t1.m_rot = orgRot;
  380.         m_t1.m_sca = orgSca;
  381.     }
  382.  
  383.     PostRender();
  384. }
  385.  
  386. bool EFFECT_FIREBALL::isDead()
  387. {
  388.     return m_pSrcBone == NULL || m_color.w < 0.0f || m_pTarget == NULL;
  389. }
  390.  
  391. D3DXVECTOR3 EFFECT_FIREBALL::GetPosition(float p)
  392. {
  393.     if(p < 0.0f)p = 0.0f;
  394.     if(p > 1.0f)p = 1.0f;
  395.  
  396.     D3DXVECTOR3 m_pos = origin * (1.0f - p) + dest * p;    //Lerp between origin and dest
  397.     m_pos.y += sin(p * D3DX_PI) * 0.15f * m_length;            //Add Arc
  398.     return m_pos;
  399. }
  400.  
  401. //////////////////////////////////////////////////////////////////////////////////////////////
  402. //                                EFFECTS    LENSFLARE                                            //
  403. //////////////////////////////////////////////////////////////////////////////////////////////
  404.  
  405. EFFECT_LENSFLARE::EFFECT_LENSFLARE(IDirect3DDevice9 *Dev, int _type, D3DXVECTOR3 _position) : EFFECT(Dev)
  406. {
  407.     m_position = _position;
  408.     m_type = _type;
  409.     m_mainAlpha = 0.0f;
  410.     m_inScreen = false;
  411.  
  412.     //Add Flares
  413.     if(m_type == 0)    //Standard flare
  414.     {
  415.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 1.0f, 0.5f, 1.0f), 0.5f, 0.7f, 0));
  416.         m_flares.push_back(FLARE(D3DXCOLOR(0.0f, 1.0f, 0.5f, 1.0f), 1.0f, 1.0f, 1));
  417.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 0.5f, 0.5f, 1.0f), 1.5f, 1.3f, 2));
  418.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 1.0f, 0.5f, 1.0f), -0.5f, 0.8f, 3));
  419.         m_flares.push_back(FLARE(D3DXCOLOR(0.0f, 1.0f, 0.5f, 1.0f), 0.4f, 1.0f, 4));
  420.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 1.0f, 0.5f, 1.0f), 0.75f, 1.0f, 5));
  421.         m_flares.push_back(FLARE(D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f), 1.8f, 1.2f, 6));
  422.         m_flares.push_back(FLARE(D3DXCOLOR(1.0f, 1.0f, 0.5f, 1.0f), 2.1f, 0.5f, 4));
  423.     }
  424.     else if(m_type == 1)        //Some other flare etc...
  425.     {
  426.         //setup your own flare here...
  427.     }
  428. }
  429.  
  430. void EFFECT_LENSFLARE::Update(float timeDelta)
  431. {
  432.     if(m_inScreen)
  433.         m_mainAlpha += timeDelta * 3.0f;
  434.     else m_mainAlpha -= timeDelta * 3.0f;
  435.  
  436.     if(m_mainAlpha > 1.0f)m_mainAlpha = 1.0f;
  437.     if(m_mainAlpha < 0.0f)m_mainAlpha = 0.0f;
  438. }
  439.  
  440. void EFFECT_LENSFLARE::Render()
  441. {
  442.     if(sprite == NULL || lensflareTexture == NULL)return;
  443.  
  444.     RECT sourceRectangles[7] = {{0, 0, 128, 128},
  445.                                 {128, 0, 256, 128},
  446.                                 {0, 128, 128, 256},
  447.                                 {128, 128, 192, 192},
  448.                                 {192, 128, 256, 192},
  449.                                 {128, 192, 192, 256},
  450.                                 {192, 192, 256, 256}};
  451.  
  452.     //Calculate screen m_position of light source
  453.     D3DXVECTOR3 screenPos;
  454.     D3DVIEWPORT9 Viewport;
  455.     D3DXMATRIX Projection, View, World;
  456.  
  457.     m_pDevice->GetViewport(&Viewport);
  458.     m_pDevice->GetTransform(D3DTS_VIEW, &View);
  459.     m_pDevice->GetTransform(D3DTS_PROJECTION, &Projection);
  460.     D3DXMatrixIdentity(&World);
  461.     D3DXVec3Project(&screenPos, &m_position, &Viewport, &Projection, &View, &World);
  462.  
  463.     //Get light position and screen center
  464.     D3DVIEWPORT9 v;
  465.     m_pDevice->GetViewport(&v);
  466.  
  467.     //Check that light source is within or without the screen bounds
  468.     if(screenPos.x < 0 || screenPos.x > v.Width ||
  469.        screenPos.y < 0 || screenPos.y > v.Height || screenPos.z > 1.0f)
  470.         m_inScreen = false;
  471.     else m_inScreen = true;
  472.  
  473.     //Lensflares aren't visible so exit function...
  474.     if(m_mainAlpha <= 0.0f)return;
  475.     
  476.     D3DXVECTOR2 lightSource = D3DXVECTOR2(screenPos.x, screenPos.y);
  477.     D3DXVECTOR2 screenCenter = D3DXVECTOR2(v.Width * 0.5f, v.Height * 0.5f);
  478.     D3DXVECTOR2 ray =  screenCenter - lightSource;
  479.  
  480.     //Draw the different flares
  481.     D3DXMATRIX sca;
  482.     sprite->Begin(D3DXSPRITE_ALPHABLEND);
  483.     for(int i=0;i<m_flares.size();i++)
  484.     {
  485.         //Calculate Flare position in screen coordinates
  486.         RECT r = sourceRectangles[m_flares[i].sourceFlare];
  487.         D3DXVECTOR2 offset = D3DXVECTOR2((r.right - r.left) / 2.0f, (r.bottom - r.top) / 2.0f) * m_flares[i].scale;
  488.         D3DXVECTOR2 flarePos = lightSource + ray * m_flares[i].place - offset;
  489.  
  490.         //Scale
  491.         D3DXMatrixScaling(&sca, m_flares[i].scale, m_flares[i].scale, 1.0f);
  492.  
  493.         //Calculate flare alpha
  494.         D3DXCOLOR m_color = m_flares[i].color;
  495.         float alpha = (D3DXVec2Length(&((flarePos + offset) - screenCenter)) + 150.0f) / (float)v.Height;
  496.         if(alpha > 1.0f)alpha = 1.0f;
  497.         m_color.a = alpha * m_mainAlpha;
  498.  
  499.         //Draw Flare
  500.         sprite->SetTransform(&sca);
  501.         sprite->Draw(lensflareTexture, &r, NULL, &D3DXVECTOR3(flarePos.x / m_flares[i].scale, flarePos.y / m_flares[i].scale, 0.0f), m_color);
  502.     }
  503.     sprite->End();
  504.  
  505.     D3DXMatrixIdentity(&sca);
  506.     sprite->SetTransform(&sca);
  507. }
  508.  
  509. bool EFFECT_LENSFLARE::isDead()
  510. {
  511.     return false;
  512. }
  513.  
  514. //////////////////////////////////////////////////////////////////////////////////////////////
  515. //                                EFFECT FIRE                                                    //
  516. //////////////////////////////////////////////////////////////////////////////////////////////
  517.  
  518. EFFECT_FIRE::EFFECT_FIRE(IDirect3DDevice9 *Dev, D3DXVECTOR3 pos, D3DXVECTOR3 scale) : EFFECT(Dev)
  519. {
  520.     m_targetScale = scale;
  521.     pos.y += scale.z * 0.25f;
  522.     m_t1.Init(pos, D3DXVECTOR3(-D3DX_PI * 0.5f, 0.0f, 0.0f), D3DXVECTOR3(0.01f, 0.01f, 0.01f));
  523.     m_pSmoke = new SMOKE(m_pDevice, 100, pos + D3DXVECTOR3(0.0f, scale.x * 0.4f, 0.0f));
  524.     m_dead = false;
  525. }
  526.  
  527. EFFECT_FIRE::~EFFECT_FIRE()
  528. {
  529.     if(m_pSmoke)delete m_pSmoke;
  530. }
  531.  
  532. void EFFECT_FIRE::Update(float timeDelta)
  533. {
  534.     m_time += timeDelta * 0.34f;
  535.  
  536.     if(!m_dead)
  537.     {
  538.         if(m_t1.m_sca.x < m_targetScale.x)m_t1.m_sca.x += timeDelta;
  539.         if(m_t1.m_sca.y < m_targetScale.y)m_t1.m_sca.y += timeDelta;
  540.         if(m_t1.m_sca.z < m_targetScale.z)m_t1.m_sca.z += timeDelta;
  541.     }
  542.     else m_t1.m_sca -= D3DXVECTOR3(1.5f, 1.5f, 1.5f) * timeDelta;
  543.  
  544.     if(m_pSmoke)m_pSmoke->Update(timeDelta);
  545. }
  546.  
  547. void EFFECT_FIRE::Render()
  548. {
  549.     if(billboardMesh == NULL || isDead())return;
  550.  
  551.     PreRender();    
  552.  
  553.     m_pDevice->SetTexture(0, fireTexture);
  554.     m_pDevice->SetTexture(1, noiseTexture);
  555.  
  556.     for(int i=0;i<7;i++)
  557.     {
  558.         m_t1.m_rot.y = m_time * 0.3f + i * D3DX_PI * 0.1428f;
  559.         fireVertexShader.SetMatrix(fireMatW, m_t1.GetWorldMatrix());
  560.         fireVertexShader.SetFloat(fireOffset, m_t1.m_rot.y + m_t1.m_pos.x + m_t1.m_pos.z);
  561.         billboardMesh->DrawSubset(0);
  562.     }
  563.  
  564.     PostRender();
  565.  
  566.     if(m_pSmoke)m_pSmoke->Render();
  567. }
  568.  
  569. bool EFFECT_FIRE::isDead()
  570. {
  571.     return m_dead && (m_t1.m_sca.x <= 0.0f || m_t1.m_sca.y <= 0.0f || m_t1.m_sca.z <= 0.0f);
  572. }
  573.  
  574. void EFFECT_FIRE::Kill()
  575. {
  576.     m_dead = true; 
  577.     if(m_pSmoke)
  578.         m_pSmoke->Kill();
  579. }
  580.  
  581. void EFFECT_FIRE::PreRender()
  582. {
  583.     //Enable alpha blending
  584.     m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  585.     m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
  586.     m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  587.     m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  588.     m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
  589.     m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
  590.     m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
  591.     m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  592.     m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, false);
  593.     m_pDevice->SetRenderState(D3DRS_LIGHTING, false);
  594.  
  595.     //Set vertex shader variables
  596.     D3DXMATRIX view, proj;
  597.     m_pDevice->GetTransform(D3DTS_VIEW, &view);
  598.     m_pDevice->GetTransform(D3DTS_PROJECTION, &proj);
  599.  
  600.     m_camEye = D3DXVECTOR3(view(0,2), 0.0f, view(2,2));
  601.     D3DXVec3Normalize(&m_camEye, &m_camEye);    
  602.  
  603.     fireVertexShader.SetMatrix(fireMatVP, view * proj);
  604.     fireVertexShader.SetFloat(fireTime, m_time);
  605.     fireVertexShader.SetVector3(fireDirToCam, m_camEye);
  606.  
  607.     //Set material
  608.     m_pDevice->SetMaterial(&whiteMtrl);
  609.  
  610.     //enable Shaders
  611.     fireVertexShader.Begin();
  612.     firePixelShader.Begin();
  613. }
  614.  
  615. void EFFECT_FIRE::PostRender()
  616. {
  617.     //Reset renderstates
  618.     m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
  619.     m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, true);
  620.     m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
  621.  
  622.     fireVertexShader.End();
  623.     firePixelShader.End();
  624. }
  625.  
  626. //////////////////////////////////////////////////////////////////////////////////////////////
  627. //                                EFFECT SELECTED                                                //
  628. //////////////////////////////////////////////////////////////////////////////////////////////
  629.  
  630. EFFECT_SELECTED::EFFECT_SELECTED(IDirect3DDevice9 *Dev) : EFFECT(Dev) {}
  631. void EFFECT_SELECTED::Update(float timeDelta) {}
  632. bool EFFECT_SELECTED::isDead(){return false;}
  633.  
  634. void EFFECT_SELECTED::Render()
  635. {
  636.     PreRender();
  637.  
  638.     //Spinning quad
  639.     m_pDevice->SetTexture(0, selectedTexture);
  640.     effectVertexShader.SetMatrix(effectMatW, m_t.GetWorldMatrix());
  641.     billboardMesh->DrawSubset(0);
  642.  
  643.     PostRender();
  644. }
  645.  
  646. void EFFECT_SELECTED::Set(float health, D3DXVECTOR3 pos, float rot, float scale)
  647. {
  648.     m_t.m_pos = pos;
  649.     m_t.m_rot.y = rot;
  650.     m_t.m_sca = D3DXVECTOR3(scale, 1.0f, scale);
  651.     m_color = D3DXVECTOR4(1.0f - health, health, 0.2f, 0.5f);
  652. }
  653.  
  654. //////////////////////////////////////////////////////////////////////////////////////////////
  655. //                                EFFECT TRAINING                                                //
  656. //////////////////////////////////////////////////////////////////////////////////////////////
  657.  
  658. EFFECT_TRAINING::EFFECT_TRAINING(IDirect3DDevice9 *Dev) : EFFECT(Dev)
  659. {
  660.     m_t.m_rot.x = -D3DX_PI * 0.5f;
  661.     m_t.m_sca = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
  662. }
  663.  
  664. void EFFECT_TRAINING::Update(float timeDelta)
  665. {
  666.     m_t.m_rot.y += timeDelta;
  667.  
  668.     if(m_t.m_sca.x < 2.0f)
  669.         m_t.m_sca += D3DXVECTOR3(timeDelta, timeDelta, timeDelta);
  670. }
  671.  
  672. void EFFECT_TRAINING::Render()
  673. {
  674.     PreRender();
  675.  
  676.     m_pDevice->SetTexture(0, trainingTexture);
  677.     D3DXVECTOR3 rot = m_t.m_rot;
  678.     for(int i=0;i<12;i++)
  679.     {
  680.         m_t.m_rot.y = rot.y + i * D3DX_PI * 0.077f;
  681.         effectVertexShader.SetMatrix(effectMatW, m_t.GetWorldMatrix());
  682.         billboardMesh->DrawSubset(0);
  683.     }
  684.     m_t.m_rot = rot;
  685.  
  686.     PostRender();
  687. }
  688.  
  689. bool EFFECT_TRAINING::isDead(){return false;}
  690.  
  691. void EFFECT_TRAINING::Set(float progress, D3DXVECTOR3 pos)
  692. {
  693.     m_t.m_pos = pos;
  694.     m_color = D3DXVECTOR4(progress * 0.1f, progress * 0.1f, progress, 1.0f);
  695. }
  696.